package com.jh.cloud.bus.util;

import com.jh.cloud.bus.entity.event.RemoteAppEvent;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * {@link com.jh.cloud.bus.entity.event.RemoteAppEvent} 监听器，将事件数据发送HTTP请求到目标机器
 */
@Component
public class HttpRemoteAppEventListener implements SmartApplicationListener {

    private RestTemplate restTemplate = new RestTemplate();
    private DiscoveryClient discoveryClient;
    private String currentServiceName;

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return RemoteAppEvent.class.isAssignableFrom(eventType)
                || ContextRefreshedEvent.class.isAssignableFrom(eventType);
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {

        if (event instanceof RemoteAppEvent) {
            onRemoteApplicationEvent((RemoteAppEvent) event);
        }

        if (event instanceof ContextRefreshedEvent) {
            onRefreshApplicationEvent((ContextRefreshedEvent) event);
        }
    }

    private void onRefreshApplicationEvent(ContextRefreshedEvent event) {
        ApplicationContext context = event.getApplicationContext();
        discoveryClient = context.getBean(DiscoveryClient.class);
        currentServiceName = context.getEnvironment().getProperty("spring.application.name");
    }

    private void onRemoteApplicationEvent(RemoteAppEvent event) {

        Object source = event.getSource();
        String appName = event.getAppName();

        List<ServiceInstance> serviceInstances = discoveryClient.getInstances(appName);
        if (!CollectionUtils.isEmpty(serviceInstances)) {
            serviceInstances.forEach(instance -> {

                String rootUrl = (instance.isSecure() ? "https://" : "http://")
                        + instance.getHost() + ":"
                        + instance.getPort();

                String url = rootUrl + "/receive/remote/event";

                Map<String, Object> data = new HashMap<>(4);
                data.put("sender", currentServiceName);
                data.put("value", source);
                data.put("type", RemoteAppEvent.class.getName());

                // 发送请求
                String responseContent = restTemplate.postForObject(url, data, String.class);

            });
        }

    }
}
